package com.yeyks.controller.activity;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yeyks.account.dal.domain.AccountInfo;
import com.yeyks.annotation.NeedToken;
import com.yeyks.common.ajax.AjaxResponseBody;
import com.yeyks.common.constants.AccountType;
import com.yeyks.common.exception.ServiceException;
import com.yeyks.common.param.PageParam;
import com.yeyks.common.param.activity.ActivityTSStatParam;
import com.yeyks.common.param.activity.AddUserInviteWhiteParam;
import com.yeyks.common.param.activity.UpdateUserInviteWhiteParam;
import com.yeyks.common.result.activity.ActivityTSResult;
import com.yeyks.common.result.activity.ActivityUserInviteChildResult;
import com.yeyks.common.result.activity.ActivityUserInviteResult;
import com.yeyks.common.utils.ObjectConvertUtil;
import com.yeyks.commonReference.service.order.OrderHeadService;
import com.yeyks.consumer.dal.domain.UserInfo;
import com.yeyks.consumer.dal.domain.UserInviteRelation;
import com.yeyks.consumer.dal.domain.UserInviteWhiteList;
import com.yeyks.consumer.param.UserInfo.UserInfoQueryByParentIdParam;
import com.yeyks.consumer.service.UserInfoService;
import com.yeyks.consumer.service.UserInviteRelationService;
import com.yeyks.consumer.service.UserInviteWhiteListService;
import com.yeyks.order.dal.domain.OrderHead;
import com.yeyks.web.AccountUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(tags = "v3.8.2活动推手")
@RestController
@Slf4j
@RequestMapping("/activity/ts")
public class ActivityTSController {

    @Autowired
    private UserInviteWhiteListService userInviteWhiteListService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private OrderHeadService orderHeadService;

    @Autowired
    private UserInviteRelationService userInviteRelationService;

    @ApiOperation(value = "v3.8.2活动推手总统计", response = ActivityTSResult.class)
    @PostMapping(value = "/total")
    public AjaxResponseBody<List<ActivityTSResult>> total(@Validated ActivityTSStatParam param) {
        List<ActivityTSResult> results = userInviteWhiteListService.statTotal(param);
        return AjaxResponseBody.success(results);
    }


    @ApiOperation(value = "v3.8.2学生、社会推手列表", response = ActivityUserInviteResult.class)
    @PostMapping(value = "/student/query")
    public AjaxResponseBody userPageList(@Validated PageParam pageParam,
                                         @ApiParam(name = "type", value = "1：学生  2：社会", allowableValues = "1,2")
                                         @RequestParam(value = "type", defaultValue = "1") Integer type) {
        long startTime = System.currentTimeMillis();
        AjaxResponseBody body = null;
        List<ActivityUserInviteResult> list = userInviteWhiteListService.queryByPage(pageParam, type);
        //参数组装（2020/02/07 更新返回数据的结构），只展示邀请人数大于0的用户
        convertParam(list);
        list.removeIf(activityUserInviteResult -> activityUserInviteResult.getInviteCount() == 0);
        int count = userInviteWhiteListService.count(new QueryWrapper<UserInviteWhiteList>()
                .eq(UserInviteWhiteList.TYPE, type));
        Map<String, Object> map = Maps.newHashMap();
        map.put("count", count);
        if (!CollectionUtils.isEmpty(list)) {
            map.put("list", list);
        } else {
            map.put("list", Lists.newArrayList());
        }
        body = AjaxResponseBody.success(map);
        long endTime = System.currentTimeMillis();
        log.info("查询时间为：{}毫秒",(endTime - startTime));
        return body;
    }

    @NeedToken
    @ApiOperation("v3.8.2黑名单操作")
    @PostMapping("/enable")
    public AjaxResponseBody enableUserInvite(@RequestParam(value = "id") Integer id,
                                             @ApiParam(name = "status", value = "0加入黑名单， 1移除黑名单", allowableValues = "0,1")
                                             @RequestParam(value = "status") Integer status) {
        AjaxResponseBody body = AjaxResponseBody.failed();
        AccountInfo loginUser = AccountUtils.getLoginUser();
        if (loginUser.getType() != AccountType.Administrator) {
            throw new ServiceException("没有权限操作");
        }
        if (status != 1 && status != 0) {
            throw new ServiceException("状态传输错误");
        }
        UserInviteWhiteList userInviteWhiteList = userInviteWhiteListService.getOne(new QueryWrapper<UserInviteWhiteList>().eq(UserInviteWhiteList.ID, id));
        if (null == userInviteWhiteList) {
            throw new ServiceException("不存在该用户");
        }
        userInviteWhiteList.setStatus(status);
        boolean flag = userInviteWhiteListService.updateById(userInviteWhiteList);
        if (flag) {
            body = AjaxResponseBody.success("操作黑名单成功");
        }
        return body;
    }

    @NeedToken
    @ApiOperation("v3.8.2添加学生、社会推手")
    @PostMapping("/add")
    public AjaxResponseBody addUserInvite(@Validated AddUserInviteWhiteParam param) {

        AjaxResponseBody body = AjaxResponseBody.failed();
        AccountInfo loginUser = AccountUtils.getLoginUser();
        if (loginUser.getType() != AccountType.Administrator) {
            throw new ServiceException("没有权限操作");
        }
        if (param.getType() != 1 && param.getType() != 2) {
            throw new ServiceException("添加类型输入错误");
        }
        //根据手机号查询userId
        UserInfo user = userInfoService.getOne(new QueryWrapper<UserInfo>().eq(UserInfo.PHONE, param.getPhone()));
        if (null == user) {
            throw new ServiceException("该手机号还没注册，请先注册，再进行添加推手");
        }
        UserInviteWhiteList userInviteWhiteList = ObjectConvertUtil.convertObject(param, UserInviteWhiteList.class);
        userInviteWhiteList.setUserId(user.getId());
        userInviteWhiteList.setStatus(1);
        userInviteWhiteList.setCreateTime(new Date());
        boolean save = userInviteWhiteListService.save(userInviteWhiteList);
        if (save) {
            body = AjaxResponseBody.success("添加推手成功");
        }

        return body;
    }

    @NeedToken
    @ApiOperation("v3.8.2编辑学生、社会推手")
    @PostMapping("/edit")
    public AjaxResponseBody editUserInvite(@Validated UpdateUserInviteWhiteParam param) {

        AjaxResponseBody body = AjaxResponseBody.failed();
        AccountInfo loginUser = AccountUtils.getLoginUser();
        if (loginUser.getType() != AccountType.Administrator) {
            throw new ServiceException("没有权限操作");
        }
        UserInviteWhiteList one = userInviteWhiteListService.getOne(new QueryWrapper<UserInviteWhiteList>().eq(UserInviteWhiteList.ID, param.getId()));
        if (null == one) {
            throw new ServiceException("不存在该用户");
        }
        UserInviteWhiteList userInviteWhiteList = ObjectConvertUtil.convertObject(param, UserInviteWhiteList.class);
        boolean flag = userInviteWhiteListService.updateById(userInviteWhiteList);
        if (flag) {
            body = AjaxResponseBody.success("编辑学生推手成功");
        }
        return body;
    }


    @NeedToken
    @ApiOperation("v3.8.2分页查询邀请人数")
    @PostMapping("/query/child")
    public AjaxResponseBody queryChildUser(@Validated PageParam pageParam,
                                           @ApiParam(name = "userId", value = "用户Id")
                                           @RequestParam(value = "userId", required = true) Integer userId) {
        AjaxResponseBody body = null;
        AccountInfo loginUser = AccountUtils.getLoginUser();
        if (loginUser.getType() != AccountType.Administrator) {
            throw new ServiceException("没有权限操作");
        }
        if (null == userId) {
            throw new ServiceException("用户Id不能为空");
        }
        Map<String, Object> map = Maps.newHashMap();

        UserInfoQueryByParentIdParam parentIdParam = new UserInfoQueryByParentIdParam();
        //不包含某个类型
        parentIdParam.setNotInType(2);
        parentIdParam.setParentId(userId);
        parentIdParam.setPageNum(pageParam.getPageNum());
        parentIdParam.setPageSize(pageParam.getPageSize());
        List<UserInfo> userInfoList = userInfoService.queryUserByParentIdPage(parentIdParam);

        List<ActivityUserInviteChildResult> results = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(userInfoList)) {
            userInfoList.forEach(userInfo -> {
                ActivityUserInviteChildResult result = new ActivityUserInviteChildResult();
                result.setId(userInfo.getId());
                result.setPhone(userInfo.getPhone());
                List<OrderHead> orderList = orderHeadService.list(new QueryWrapper<OrderHead>().eq(OrderHead.USER_ID, userInfo.getId())
                        .notIn(OrderHead.STATUS, Lists.newArrayList(1, 4, 8)));
                if (!CollectionUtils.isEmpty(orderList)) {
                    //查询邀请人下单数
                    result.setOrderCount(orderList.size());
                    //下单金额
                    long orderAmount = orderList.stream().filter(orderHead -> orderHead.getSnapshotTotalFee() != null)
                            .mapToLong(OrderHead::getSnapshotTotalFee).sum();
                    result.setOrderAmount(orderAmount);
                }
                results.add(result);
            });
        }
        int count = userInfoService.queryUserByParentIdCount(parentIdParam);
        map.put("count", count);
        map.put("list", results);
        body = AjaxResponseBody.success(map);
        return body;
    }

    /**
     * 参数组装
     *
     * @param list 集合参数组装
     */
    private void convertParam(List<ActivityUserInviteResult> list) {
        if (!CollectionUtils.isEmpty(list)) {
            List<Integer> ids = list.stream().map(ActivityUserInviteResult::getUserId).collect(Collectors.toList());
            List<UserInfo> userList = userInfoService.queryChildUser(ids);
            List<UserInviteRelation> userInviteRelationList = selectAllInviteRelation(ids);
            List<OrderHead> orderHeadAllList = selectAllOrderHead(userList);
            List<OrderHead> orderList = Lists.newArrayList();
            List<UserInviteRelation> userInviteList = Lists.newArrayList();
            list.forEach(activityUserInviteResult -> {
                if(!CollectionUtils.isEmpty(userInviteRelationList)){
                    for(UserInviteRelation userInviteRelation : userInviteRelationList){
                        if(userInviteRelation.getParentId().equals(activityUserInviteResult.getUserId())){
                            userInviteList.add(userInviteRelation);
                        }
                    }
                    activityUserInviteResult.setInviteCount(userInviteList.size());
                }
                if (!CollectionUtils.isEmpty(userInviteList)) {
                    List<Integer> userIds = userInviteList.stream().map(UserInviteRelation::getUserId).collect(Collectors.toList());
                    for(OrderHead oh : orderHeadAllList){
                        if(!userIds.contains(oh.getUserId())){
                            continue;
                        }
                        orderList.add(oh);
                    }
                    if (!CollectionUtils.isEmpty(orderList)) {
                        //查询邀请人下单数
                        activityUserInviteResult.setOrderCount(orderList.size());
                        //查询邀请人下单金额
                        long orderAmount = orderList.stream().filter(orderHead -> orderHead.getSnapshotTotalFee() != null)
                                .mapToLong(OrderHead::getSnapshotTotalFee).sum();
                        activityUserInviteResult.setOrderAmount(orderAmount);
                    }
                }
                orderList.clear();
                userInviteList.clear();
            });
        }
    }

    private List<OrderHead> selectAllOrderHead(List<UserInfo> userList){

        List<Integer> ids = userList.stream().map(UserInfo::getId).collect(Collectors.toList());
        return orderHeadService.list(new QueryWrapper<OrderHead>().in(OrderHead.USER_ID, ids)
                .notIn(OrderHead.STATUS, Lists.newArrayList(1, 4, 8)));
    }

    private List<UserInviteRelation> selectAllInviteRelation(List<Integer> ids){

        List<UserInviteRelation> list = userInviteRelationService.list(new QueryWrapper<UserInviteRelation>()
                .in(UserInviteRelation.PARENT_ID, ids)
                .notIn(UserInviteRelation.TYPE, Lists.newArrayList(2)));
        return list;
    }



}
